/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.perlak.camel;

import com.perlak.logs.LoggingClass;
import org.apache.camel.Processor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;

/**
 *
 * @author mateusz
 */
public abstract class BaseProcessor implements Processor, LoggingClass {

  /**
   * Error code for HTTP server error.
   */
  private static final int HTTP_ERROR_CODE = 500;
  /**
   * Name of header for message that had error.
   */
  public static final String ERROR_MESSAGE_HEADER = "ERROR";
  /**
   *  Name of header for message request which created error.
   */
  public static final String ERROR_MESSAGE_REQUEST_HEADER = "ERROR_REQUEST";
  /**
   * Content type constant.
   */
  public static final String CONTENT_TYPE = "Content-Type";
  /**
   * Xml type constant.
   */
  public static final String CONTENT_XML = "text/xml";
  /**
   * Text type constant.
   */
  public static final String CONTENT_PLAIN = "text/plain";
  /**
   * General error message text.
   */
  public static final String GENERAL_ERROR_MESSAGE =
          "A General Error Occured in the System, Log Was Created of This Event.";

  /**
   * Checks if message is not error message, if it is then passes error message.
   * @param exchng Message Exchange
   * @return is not error message
   */
  protected final boolean isNotErrorMessage(final Exchange exchng) {
    if (exchng.getIn().getHeader(ERROR_MESSAGE_HEADER) != null) {
      exchng.setOut(exchng.getIn());
      return false;
    } else {
      return true;
    }
  }

  /**
   * Reads message from Exchange to XML.
   * @param exchng Exchange message.
   * @param logBody if body of message should be logged.
   * @return Xml of the message
   * @throws IOException Thrown when error with reading exchange message.
   */
  protected final String readMessage(final Exchange exchng, final boolean logBody) throws IOException {
    if (logBody) {
      getLog().debug("reading message: {}" + exchng.toString());
    }
    Message inMsg = exchng.getIn();
    getLog().debug("in message body class name: {}", inMsg.getBody().getClass().getName());
    StringBuilder sb = new StringBuilder();
    // if message is InputStream - direct from Jetty request.
    if (inMsg.getBody() instanceof InputStream) {
      InputStream str = (InputStream) inMsg.getBody();

      BufferedReader reader = null;
      String line = "";
      try {
        reader = new BufferedReader(new InputStreamReader(str, "UTF-8"));
        while ((line = reader.readLine()) != null) {
          sb.append(line).append("\n");
        }
      } finally {
        if (reader != null) {
          reader.close();
        }
        str.close();
      }
    } else if (inMsg.getBody() instanceof String) {
      sb.append((String) inMsg.getBody());
    }
    return sb.toString();
  }

  /**
   * Reads message from Exchange to XML.
   * @param exchng Exchange message.
   * @return Xml of the message
   * @throws IOException Thrown when error with reading exchange message.
   */
  protected final String readMessage(final Exchange exchng) throws IOException {
    return readMessage(exchng, true);
  }

  /**
   * Prepares generic error response.
   * @param exchng exchange
   */
  protected final void prepareStandardErrorMessage(final Exchange exchng) {
    exchng.getOut().setHeader(CONTENT_TYPE, CONTENT_PLAIN);
    exchng.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, HTTP_ERROR_CODE);
    exchng.getOut().setHeader(ERROR_MESSAGE_HEADER, true);
    exchng.getOut().setBody(GENERAL_ERROR_MESSAGE);

  }

  private void setContentPlainText(final Exchange exchng) {
    exchng.getOut().setHeader(CONTENT_TYPE, CONTENT_PLAIN);
  }

  /**
   * Sets text/xml mime type for output message
   * @param exchng Echange message.
   */
  protected final void setOutputXmlTypeHeader(final Exchange exchng) {
    exchng.getOut().setHeader(CONTENT_TYPE, CONTENT_XML);
  }

  @Override
  public void process(Exchange exchange) throws Exception {
    if (isNotErrorMessage(exchange)) {
      processNoError(exchange);
    }
  }

  protected abstract void processNoError(Exchange exchange) throws Exception;
}
